/* 
 * File:   JServerStub.cpp
 * Author: johnneyshi
 * 
 * Created on 2013年5月14日, 下午8:10
 */

#include "JBaseFile.h"
#include "JServerStub.h"
#include "JStubArgument.h"
#include "JWorkingCopies.h"
#include "JException.h"
#include <string>
#include <list>
#include "JCommitConflict.h"
#include "JRepositoryEntry.h"
#include "JInOutPutFstream.h"
#include "JRepositoryConfig.h"
#include "JUpdateConflict.h"
#include "Convert.h"

JRepositoryEntry JServerStub::entry;

JServerStub::JServerStub() 
{
    //初始化JInOutPut*
    pInStrea = new JInOutPutFstream(JRepositoryConfig::repositoryInTempStreamFileName);

    
    pOutStrea = new JInOutPutFstream(JRepositoryConfig::repositoryOutTempStreamFileName);
    
}

JServerStub::~JServerStub() 
{
    
}

JCommitConflict JServerStub::Commit(JInOutPut& _strea,JWorkingCopies& _workingCopies,JWorkingCopiesBaseFile& _copyBaseFile,JBaseFile& _baseFile)
{
    //JRepositoryEntry entry;
    return entry.Commit(_strea,_workingCopies,_copyBaseFile,_baseFile);
}

JRepositorySearchResult JServerStub::Search(JInOutPut& _strea,JWorkingCopies& _workingCopies,JString& _fullFileName, JString& _versionID)
{
    return entry.Search(_strea,_workingCopies,_fullFileName.str,Convert::ToInt(_versionID.str));
    //return entry.Search(_strea,_workingCopies,_fullFileName,_versionID);
}

JUpdateConflict JServerStub::Update(JInOutPut& _strea, JWorkingCopies& _workingCopies, JWorkingCopiesBaseFile& _copyBaseFile)
{
    //return 
}

void JServerStub::PackReturnValue(JStubArgument& _arg)
{
    int allSize = 0;
    _arg.PackStubMessage(*pOutStrea,allSize);
}

JRepositoryOperationResult JServerStub::GetLock(JWorkingCopies& _workingCopies,JString& lockType)
{
    return entry.GetLock(_workingCopies,lockType);
}

JRepositoryOperationResult JServerStub::ReleaseLock(JWorkingCopies& _workingCopies)
{
    return entry.ReleaseLock(_workingCopies);
}



bool JServerStub::AnalysisCommand()
{
        ((JInOutPutFstream*)pInStrea)->OpenStream(std::ios::binary | std::ios::in);
        ((JInOutPutFstream*)pOutStrea)->OpenStream(std::ios::binary | std::ios::out | std::ios::trunc);
        std::string funcName;
        std::list<std::string> listArg;
        int classSize = JStubArgument::UnPackStubMessageHead(*pInStrea,funcName,listArg);
        if(funcName == "Commit")
        {
            if(listArg.size() == 3)
            {
                std::list<std::string>::iterator iteArg = listArg.begin();
                JWorkingCopies* pWorkingCopies = NULL;
                JWorkingCopiesBaseFile* pWorkingCopiesBaseFile = NULL;
                JBaseFile* pBaseFile = NULL;
                if(*iteArg == "JWorkingCopies&")
                {
                    pWorkingCopies = (JWorkingCopies*)JStubArgument::StubArgumentFactory(*pInStrea,*iteArg);
                }
                else
                {
                    throw JException("Invoke function error!");
                }
                ++iteArg;
                if(*iteArg == "JWorkingCopiesBaseFile&")
                {
                    pWorkingCopiesBaseFile = (JWorkingCopiesBaseFile*)JStubArgument::StubArgumentFactory(*pInStrea,*iteArg);
                }
                else
                {
                    throw JException("Invoke function error!");
                }
                ++iteArg;
                if(*iteArg == "JBaseFile&")
                {
                    //这里需要特殊处理，因为穿过来的文件不会是baseFile，是dir或者file
                    if(pWorkingCopiesBaseFile->dirOrFile == "dir")
                    {
                        pBaseFile = (JBaseFile*)JStubArgument::StubArgumentFactory(*pInStrea,"JDir&");
                    }
                    else
                    {
                        pBaseFile = (JBaseFile*)JStubArgument::StubArgumentFactory(*pInStrea,"JFile&");
                    }
                }
                else
                {
                    throw JException("Invoke function error!");
                }
                JCommitConflict commitConflict = Commit(*pInStrea,*pWorkingCopies,*pWorkingCopiesBaseFile,*pBaseFile);
                PackReturnValue(commitConflict);
                delete pWorkingCopies;
                delete pWorkingCopiesBaseFile;
                delete pBaseFile;
            }
        } 
        else if (funcName == "Search") 
        {
            if(listArg.size() == 3)
            {
                //JRepositorySearchResult Search(JInOutPut& _strea,JWorkingCopies& _workingCopies,JString& _fullFileName, JString& _versionID)
                std::list<std::string>::iterator iteArg = listArg.begin();
                JWorkingCopies* pWorkingCopies = NULL;
                JString* pFullFileName = NULL;
                JString* pVersionID = NULL;
                if (*iteArg == "JWorkingCopies&") 
                {
                    pWorkingCopies = (JWorkingCopies*) JStubArgument::StubArgumentFactory(*pInStrea, *iteArg);
                }
                else 
                {
                    throw JException("Invoke function error!");
                }
                ++iteArg;
                if (*iteArg == "JString&") 
                {
                    pFullFileName = (JString*) JStubArgument::StubArgumentFactory(*pInStrea, *iteArg);
                }
                else 
                {
                    throw JException("Invoke function error!");
                }
                ++iteArg;
                if(*iteArg == "JString&")
                {
                    pVersionID = (JString*)JStubArgument::StubArgumentFactory(*pInStrea,*iteArg);
                }
                else
                {
                    throw JException("Invoke function error!");
                }
                JRepositorySearchResult searchResult = Search(*pInStrea,*pWorkingCopies,*pFullFileName,*pVersionID);
                PackReturnValue(searchResult);
                delete pWorkingCopies;
                delete pFullFileName;
                delete pVersionID;
            }
        }
        else if(funcName == "GetLock")
        {
            if(listArg.size() == 2)
            {
                std::list<std::string>::iterator iteArg = listArg.begin();
                JWorkingCopies* pWorkingCopies = NULL;
                JString* pString = NULL;
                if(*iteArg == "JWorkingCopies&")
                {
                    pWorkingCopies = (JWorkingCopies*)JStubArgument::StubArgumentFactory(*pInStrea,"JWorkingCopies&");
                }
                ++iteArg;
                if(*iteArg == "JString&")
                {
                    pString = (JString*)JStubArgument::StubArgumentFactory(*pInStrea,"JString&");
                }
                JRepositoryOperationResult result = GetLock(*pWorkingCopies,*pString);
                PackReturnValue(result);
                delete pWorkingCopies;
                delete pString;
            }
            else
            {
                throw JException("Invoke function error!");
            }
        }
        else if(funcName == "ReleaseLock")
        {
            if(listArg.size() == 1)
            {
                JWorkingCopies* pWorkingCopies = NULL;
                if(listArg.front() == "JWorkingCopies&")
                {
                    pWorkingCopies = (JWorkingCopies*)JStubArgument::StubArgumentFactory(*pInStrea,"JWorkingCopies&");
                }
                JRepositoryOperationResult result = ReleaseLock(*pWorkingCopies);
                PackReturnValue(result);
                delete pWorkingCopies;
            }
            //break;
        }
        ((JInOutPutFstream*)pInStrea)->CloseStream();
        ((JInOutPutFstream*)pOutStrea)->CloseStream();
        if(funcName == "ReleaseLock")
        {
            return true;
        }
        return false;
}

//JStubArgument* JServerStub::StubArgumentFactory(JInOutPut& _strea,std::string _arg)
//{
//    if(_arg == "JWorkingCopies&")
//    {
//        JWorkingCopies* pWorkingCopies = new JWorkingCopies();
//        pWorkingCopies->UnPackStubMessage(_strea);
//        return pWorkingCopies;
//    }
//    else if(_arg == "JWorkingCopiesBaseFile&")
//    {
//        JWorkingCopiesBaseFile* pWorkingCopiesBaseFile = new JWorkingCopiesBaseFile();
//        pWorkingCopiesBaseFile->UnPackStubMessage(_strea);
//        return pWorkingCopiesBaseFile;
//    }
//    else if(_arg == "JFile&")
//    {
//        JFile* pFile = new JFile();
//        pFile->UnPackStubMessage(_strea);
//        return pFile;
//    }
//    else if(_arg == "JDir&")
//    {
//        JDir* pDir = new JDir();
//        pDir->UnPackStubMessage(_strea);
//        return pDir;
//    }
//    else if(_arg == "JString&")
//    {
//        JString* pStr = new JString();
//        pStr->UnPackStubMessage(_strea);
//        return pStr;
//    }
//    return NULL;
//}